package cn.omisheep.commons.util;


import org.apache.commons.codec.binary.Base64;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

/**
 * @author zhouxinchen[1269670415@qq.com]
 * @since 1.0.0
 */
public class RSAHelper {

    private RSAHelper() {
        throw new UnsupportedOperationException();
    }

    public static class RSAKeyPair {
        private final String publicKey;
        private final String privateKey;

        public RSAKeyPair(String publicKey,
                          String privateKey) {
            this.publicKey  = publicKey;
            this.privateKey = privateKey;
        }

        public String getPublicKey() {
            return publicKey;
        }

        public String getPrivateKey() {
            return privateKey;
        }

        @Override
        public String toString() {
            return "\npublicKey=\n" + publicKey +
                    "\nprivateKey=\n" + privateKey;
        }
    }

    /**
     * 随机生成密钥对
     *
     * @return RSAKeyPair密钥对
     * @throws NoSuchAlgorithmException e
     */
    public static RSAKeyPair genKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(1024, new SecureRandom());
        KeyPair keyPair = keyPairGen.generateKeyPair();

        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey  publicKey  = (RSAPublicKey) keyPair.getPublic();

        String publicKeyString  = new String(Base64.encodeBase64(publicKey.getEncoded()));
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));

        return new RSAKeyPair(publicKeyString, privateKeyString);
    }


    /**
     * RSA公钥加密
     *
     * @param str       明文
     * @param publicKey 公钥
     * @return 加密字符串
     */
    public static String encrypt(String str,
                                 String publicKey) {
        try {
            return RSAUtils.encryptString(RSAUtils.getPublicKey(publicKey), str);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }


    /**
     * RSA私钥解密
     *
     * @param str        秘文
     * @param privateKey 私钥
     * @return 明文
     */
    public static String decrypt(String str,
                                 String privateKey) {
        try {
            return RSAUtils.decryptString(RSAUtils.getPrivateKey(privateKey), bugfix(str));
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }


    public static String bugfix(String text) {
        return text.replaceAll(" ", "+");
    }

}